package org.example.rowing.controller;

import javafx.collections.FXCollections;
import javafx.fxml.FXML;
import javafx.scene.control.Alert;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import javafx.util.StringConverter;
import lombok.extern.slf4j.Slf4j;
import org.example.rowing.domain.Race;
import org.example.rowing.domain.RegistrationWithAthlete;
import org.example.rowing.domain.Team;
import org.example.rowing.enums.BoatTypeEnum;
import org.example.rowing.service.RaceInfoService;
import org.example.rowing.service.RegistrationInfoService;
import org.example.rowing.service.TeamInfoService;
import org.example.rowing.vo.AthleteVO;
import org.example.rowing.vo.RaceVO;
import org.example.rowing.vo.RegistrationVO;
import org.example.rowing.vo.TeamVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Controller
@Slf4j
public class UpdateCKRegistrationController {
    @FXML
    private ComboBox<Race> raceComboBox;
    @FXML
    private ComboBox<Team> teamComboBox;
    @FXML
    private ComboBox<AthleteVO> athleteComboBox1;
    @FXML
    public TextField athleteTextField1;
    @FXML
    private ComboBox<AthleteVO> athleteComboBox2;
    @FXML
    public TextField athleteTextField2;
    @FXML
    private ComboBox<AthleteVO> athleteComboBox3;
    @FXML
    public TextField athleteTextField3;
    @FXML
    private ComboBox<AthleteVO> athleteComboBox4;
    @FXML
    public TextField athleteTextField4;
    @FXML
    public Label athleteLabel1, athleteLabel2, athleteLabel3, athleteLabel4;
    @FXML
    private Label popupTitle;

    private RegistrationVO registrationToEdit;
    private String raceType = "";

    @Autowired
    private TeamInfoService teamInfoService;
    @Autowired
    private RaceInfoService raceInfoService;
    @Autowired
    private RegistrationInfoService registrationInfoService;

    // 用于在弹出框初始化时设置事件信息（用于编辑）
    public void initialize(RegistrationVO registrationVO) {
        // 设置转换器，使下拉框只显示 name
        raceComboBox.setConverter(new StringConverter<Race>() {
            @Override
            public String toString(Race race) {
                return race == null ? "" : race.getId() + ". " + race.getName();
            }
            @Override
            public Race fromString(String string) {
                // 一般不需要转换回对象，可返回 null 或自行实现
                return null;
            }
        });
        teamComboBox.setConverter(new StringConverter<Team>() {
            @Override
            public String toString(Team team) {
                return team == null ? "" : team.getId() + ". " + team.getName();
            }
            @Override
            public Team fromString(String string) {
                // 一般不需要转换回对象，可返回 null 或自行实现
                return null;
            }
        });
        athleteComboBox1.setConverter(new StringConverter<AthleteVO>() {
            @Override
            public String toString(AthleteVO athleteVO) {
                return athleteVO == null ? "" : athleteVO.getId() + ". " + athleteVO.getName();
            }
            @Override
            public AthleteVO fromString(String string) {
                // 一般不需要转换回对象，可返回 null 或自行实现
                return null;
            }
        });
        athleteComboBox2.setConverter(new StringConverter<AthleteVO>() {
            @Override
            public String toString(AthleteVO athleteVO) {
                return athleteVO == null ? "" : athleteVO.getId() + ". " + athleteVO.getName();
            }
            @Override
            public AthleteVO fromString(String string) {
                // 一般不需要转换回对象，可返回 null 或自行实现
                return null;
            }
        });
        athleteComboBox3.setConverter(new StringConverter<AthleteVO>() {
            @Override
            public String toString(AthleteVO athleteVO) {
                return athleteVO == null ? "" : athleteVO.getId() + ". " + athleteVO.getName();
            }
            @Override
            public AthleteVO fromString(String string) {
                // 一般不需要转换回对象，可返回 null 或自行实现
                return null;
            }
        });
        athleteComboBox4.setConverter(new StringConverter<AthleteVO>() {
            @Override
            public String toString(AthleteVO athleteVO) {
                return athleteVO == null ? "" : athleteVO.getId() + ". " + athleteVO.getName();
            }
            @Override
            public AthleteVO fromString(String string) {
                // 一般不需要转换回对象，可返回 null 或自行实现
                return null;
            }
        });

        if (registrationVO != null) {
            this.registrationToEdit = registrationVO;
            popupTitle.setText("修改信息");
            loadRaces();
            raceComboBox.setValue(registrationVO.getRace());
            loadTeams(registrationVO.getRace());
            teamComboBox.setValue(registrationVO.getTeam());
            loadAthletes(registrationVO.getTeam().getId());
            List<RegistrationWithAthlete> athletes = registrationVO.getAthletes();
            List<AthleteVO> athleteVOS = getAthleteFromRWA(athletes);
            athleteComboBox1.setValue(athletes.size() > 0 ? athleteVOS.get(0) : null);
            athleteTextField1.setText(athletes.size() > 0 ? athletes.get(0).getAthleteNum() : "");
            athleteComboBox2.setValue(athletes.size() > 1 ? athleteVOS.get(1) : null);
            athleteTextField2.setText(athletes.size() > 1 ? athletes.get(1).getAthleteNum() : "");
            athleteComboBox3.setValue(athletes.size() > 2 ? athleteVOS.get(2) : null);
            athleteTextField3.setText(athletes.size() > 2 ? athletes.get(2).getAthleteNum() : "");
            athleteComboBox4.setValue(athletes.size() > 3 ? athleteVOS.get(3) : null);
            athleteTextField4.setText(athletes.size() > 3 ? athletes.get(3).getAthleteNum() : "");
        } else {
            popupTitle.setText("报名信息");
            loadRaces();
            this.registrationToEdit = null;
        }

        raceComboBox.setOnAction(event -> {
            Race race = raceComboBox.getValue();
            loadTeams(race);
        });
        teamComboBox.setOnAction(event -> {
            Team team = teamComboBox.getValue();
            loadAthletes(team.getId());
        });
    }

    private List<AthleteVO> getAthleteFromRWA(List<RegistrationWithAthlete> registrationWithAthletes) {
        List<AthleteVO> athleteVOList = new ArrayList<>();
        for (RegistrationWithAthlete registrationWithAthlete : registrationWithAthletes) {
            AthleteVO athleteCondition = new AthleteVO();
            athleteCondition.setId(registrationWithAthlete.getAthleteId());
            List<AthleteVO> athleteVOS = teamInfoService.showSearchedAthletes(athleteCondition);
            if (athleteVOS != null && !athleteVOS.isEmpty()) {
                athleteVOList.add(athleteVOS.get(0));
            }
        }
        return athleteVOList;
    }

    private void loadRaces() {
        List<Race> races = new ArrayList<>();
        List<RaceVO> raceVOS = raceInfoService.showRacesByBoatType(BoatTypeEnum.CANOE.getDisplayName());
        List<RaceVO> raceVOS1 = raceInfoService.showRacesByBoatType(BoatTypeEnum.KAYAK.getDisplayName());
        raceVOS.addAll(raceVOS1);
        for (RaceVO raceVO : raceVOS) {
            Race race = new Race(raceVO.getId(), raceVO.getName(), raceVO.getEventVO().getId(), raceVO.getDistance(),
                    raceVO.getRaceType(), raceVO.getGenderEnum(), raceVO.getRaceDate(), null, null, null,
                    null, null, null, null, null, null, raceVO.getIsLongDistance());
            races.add(race);
        }
        raceComboBox.setItems(FXCollections.observableArrayList(races));
    }

    private void loadTeams(Race race) {
        raceType = race.getRaceType();
        List<Team> teams = new ArrayList<>();
        List<TeamVO> teamVOS = teamInfoService.showTeamsByEventId(race.getEventId());
        for (TeamVO teamVO : teamVOS) {
            Team team = new Team(teamVO.getId(), teamVO.getEventVO().getId(), teamVO.getName(), teamVO.getCountry(),
                    teamVO.getCoachName(), teamVO.getInfo(), null);
            teams.add(team);
        }
        teamComboBox.setItems(FXCollections.observableArrayList(teams));
        // 根据raceType设置运动员选择框
        setAthleteComboBoxVisibility();
    }

    private List<AthleteVO> loadAthletes(Long teamId) {
        List<AthleteVO> athleteVOS = new ArrayList<>();
        if (teamId == null) {
            return athleteVOS;
        }
        AthleteVO athlete = new AthleteVO();
        athlete.setTeamId(teamId);
        athleteVOS = teamInfoService.showSearchedAthletes(athlete);
        athleteComboBox1.setItems(FXCollections.observableArrayList(athleteVOS));
        athleteComboBox2.setItems(FXCollections.observableArrayList(athleteVOS));
        athleteComboBox3.setItems(FXCollections.observableArrayList(athleteVOS));
        athleteComboBox4.setItems(FXCollections.observableArrayList(athleteVOS));
        return athleteVOS;
    }

    // 保存赛事
    @FXML
    private void handleSaveRegistration() {
        Race race = raceComboBox.getValue();
        Team team = teamComboBox.getValue();
        AthleteVO athleteVO1 = athleteComboBox1.getValue();
        AthleteVO athleteVO2 = athleteComboBox2.getValue();
        AthleteVO athleteVO3 = athleteComboBox3.getValue();
        AthleteVO athleteVO4 = athleteComboBox4.getValue();
        String athleteNum1 = athleteTextField1.getText().trim();
        String athleteNum2 = athleteTextField2.getText().trim();
        String athleteNum3 = athleteTextField3.getText().trim();
        String athleteNum4 = athleteTextField4.getText().trim();
        List<RegistrationWithAthlete> athletes = new ArrayList<>();

        if (race == null || team == null || athleteVO1 == null) {
            log.warn("请填写完整的报名信息");
            showErrorDialog("请填写完整的报名信息");
            return;
        }

        RegistrationWithAthlete rwa1 = new RegistrationWithAthlete(null, null, athleteVO1.getId(), athleteVO1.getName(), athleteNum1);
        if (Objects.equals(raceType, "单人")) {
            rwa1.setId(registrationToEdit != null ? registrationToEdit.getAthletes().get(0).getId() : null);
            athletes.add(rwa1);
        } else if (Objects.equals(raceType, "双人") && athleteVO2 != null) {
            rwa1.setId(registrationToEdit != null ? registrationToEdit.getAthletes().get(0).getId() : null);
            RegistrationWithAthlete rwa2 = new RegistrationWithAthlete(null, null, athleteVO2.getId(), athleteVO2.getName(), athleteNum2);
            rwa2.setId(registrationToEdit != null ? registrationToEdit.getAthletes().get(1).getId() : null);
            athletes.add(rwa1);
            athletes.add(rwa2);
        } else if (Objects.equals(raceType, "四人") && athleteVO3 != null && athleteVO4 != null) {
            rwa1.setId(registrationToEdit != null ? registrationToEdit.getAthletes().get(0).getId() : null);
            RegistrationWithAthlete rwa2 = new RegistrationWithAthlete(null, null, athleteVO2.getId(), athleteVO2.getName(), athleteNum2);
            rwa2.setId(registrationToEdit != null ? registrationToEdit.getAthletes().get(1).getId() : null);
            RegistrationWithAthlete rwa3 = new RegistrationWithAthlete(null, null, athleteVO3.getId(), athleteVO3.getName(), athleteNum3);
            rwa3.setId(registrationToEdit != null ? registrationToEdit.getAthletes().get(2).getId() : null);
            RegistrationWithAthlete rwa4 = new RegistrationWithAthlete(null, null, athleteVO4.getId(), athleteVO4.getName(), athleteNum4);
            rwa4.setId(registrationToEdit != null ? registrationToEdit.getAthletes().get(3).getId() : null);
            athletes.add(rwa1);
            athletes.add(rwa2);
            athletes.add(rwa3);
            athletes.add(rwa4);
        } else {
            log.warn("请填写完整的报名信息");
            showErrorDialog("请填写完整的报名信息");
            return;
        }

        RegistrationVO registrationVO = new RegistrationVO(null, race, team, athletes);

        if (registrationToEdit == null) {
            log.info("报名信息: {}", registrationVO);
            RegistrationVO regCondition = new RegistrationVO();
            regCondition.setRaceId(race.getId());
            regCondition.setTeamId(team.getId());
            List<RegistrationVO> registrationVOS = registrationInfoService.showSearchedRegistrations(regCondition);
            if (registrationVOS.size() >= 3 && !race.getIsLongDistance()) {
                showErrorDialog("当前队伍已经有3条艇报名！");
                return;
            }
        } else {
            registrationVO.setRegistrationId(registrationToEdit.getRegistrationId());
            log.info("修改信息:{}, {}", registrationVO, registrationToEdit);
        }
        registrationInfoService.saveOrUpdateRegistration(registrationVO);

        // 关闭弹窗
        closeWindow();
    }

    // 根据 raceType 设置可编辑的运动员下拉框数量
    private void setAthleteComboBoxVisibility() {
        switch (raceType) {
            case "单人":
                athleteLabel2.setVisible(false);
                athleteComboBox2.setVisible(false);
                athleteTextField2.setVisible(false);
                athleteLabel3.setVisible(false);
                athleteComboBox3.setVisible(false);
                athleteTextField3.setVisible(false);
                athleteLabel4.setVisible(false);
                athleteComboBox4.setVisible(false);
                athleteTextField4.setVisible(false);
                break;
            case "双人":
                athleteLabel2.setVisible(true);
                athleteComboBox2.setVisible(true);
                athleteTextField2.setVisible(true);
                athleteLabel3.setVisible(false);
                athleteComboBox3.setVisible(false);
                athleteTextField3.setVisible(false);
                athleteLabel4.setVisible(false);
                athleteComboBox4.setVisible(false);
                athleteTextField4.setVisible(false);
                break;
            case "四人":
                athleteLabel2.setVisible(true);
                athleteComboBox2.setVisible(true);
                athleteTextField2.setVisible(true);
                athleteLabel3.setVisible(true);
                athleteComboBox3.setVisible(true);
                athleteTextField3.setVisible(true);
                athleteLabel4.setVisible(true);
                athleteComboBox4.setVisible(true);
                athleteTextField4.setVisible(true);
                break;
            default:
                break;
        }
    }

    // 取消操作，关闭弹出框
    @FXML
    private void handleCancel() {
        closeWindow();
    }

    private void closeWindow() {
        Stage stage = (Stage) raceComboBox.getScene().getWindow();
        stage.close();
    }

    // 弹出错误提示框
    private void showErrorDialog(String message) {
        Alert alert = new Alert(Alert.AlertType.ERROR);
        alert.setTitle("输入错误");
        alert.setHeaderText(null);
        alert.setContentText(message);
        alert.showAndWait();
    }
}
